import serial
import time
import signal
import datetime
import sys
import math

# 定义一些颜色常量
class color:
    NONE = ""
    RED = "\033[31m"
    GREEN = "\033[32m"
    YELLOW = "\033[33m"
    BLUE = "\033[34m"
    MAGENTA = "\033[35m"
    CYAN = "\033[36m"
    WHITE = "\033[37m"
    RESET = "\033[0m"

# 定义一些宏定义
BUF_SIZE = 2048
CMD_MAX = 30
LINE_MAX = 80
SAVE_KEY_NUM = 100

# 全局变量
com = None
history = []
shock_time = None
max_acceleration = 0

# 控制台打印log信息
def print_log(text):
    print(text)
    sys.stdout.flush()

# 模拟蜂鸣器
def beep(frequency, duration):
    # 这里应该替换为实际的蜂鸣器控制代码
    print(f"Beep {frequency}Hz for {duration}ms")

# 获取当前时间
def get_current_time():
    return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

# 保存历史命令
def save_history(command):
    history.append(command)

# 处理shock事件
def handle_shock():
    global shock_time, max_acceleration
    shock_time = get_current_time()
    max_acceleration = read_accelerometer()  # 假设有一个函数可以读取加速度传感器值
    print_log("Shock occurred!!")
    beep(440, 500)

# 模拟读取加速度传感器
def read_accelerometer():
    # 这里应该替换为实际的加速度传感器读取代码
    return 9.8  # 模拟返回9.8m/s²的加速度

# 命令处理
def execute_command(command):
    if command == "ledOFF":
        print_log("Turning off LED...")
        com.write(b"LED_OFF\n")
        print_log("LED OFF!")
    elif command == "ledON":
        print_log("Turning on LED...")
        com.write(b"LED_ON\n")
        print_log("LED ON!")
    elif command == "ledblink":
        print_log("Blinking LED...")
        com.write(b"LED_BLINK\n")
        print_log("LED blink 1!")
        print_log("LED blink 2!")
        # ... 后略
    elif command.startswith("ledctl"):
        args = command.split()
        if len(args) < 4:
            print_log("Invalid ledctl command format")
            return
        mode = args[2]
        count = args[4]
        interval = args[6]
        print_log(f"Ledctl mode: {mode}, count: {count}, interval: {interval}")
        com.write(f"LEDCTL {mode} {count} {interval}\n".encode())
    elif command == "IMU_DEMO":
        print_log("Entering IMU DEMO mode...")
        com.write(b"IMU_DEMO\n")
        while True:
            time.sleep(0.5)
            print_log(f"{get_current_time()} U")
        print_log("Exiting IMU DEMO mode...")
    elif command == "READ_SHOCK":
        print_log("Reading shock history...")
        if shock_time is not None and max_acceleration > 0:
            print_log(f"A shock occurred at {shock_time} with a maximum acceleration of {max_acceleration}g.")
        com.write(b"READ_SHOCK\n")
    elif command == "Clear":
        print("\033c", end="")
    else:
        print_log("Input Error!!")

# 捕获Ctrl+C信号
def signal_handler(sig, frame):
    print("\nCtrl+C detected. Exiting...")
    com.close()
    sys.exit(0)

# 主函数
def main():
    signal.signal(signal.SIGINT, signal_handler)
    try:
        with serial.Serial('COM3', 115200, timeout=1) as com:
            print_log("欢迎来到祖传终端shell")
            while True:
                # 显示输入提示符
                print_log(color.BLUE + " INPUT > " + color.RESET, end="", flush=True)
                # 获取用户输入
                user_input = input().strip()
                save_history(user_input)
                # 解析用户输入
                if user_input == "exit":
                    print_log("输出结束")
                    break
                else:
                    # 执行相应命令
                    execute_command(user_input)
                # 检测是否发生摇晃
                # 这里应该替换为实际的加速度传感器检测代码
                if read_accelerometer() > 10:  # 假设加速度超过10g认为发生摇晃
                    handle_shock()
    except serial.SerialException as e:
        print_log(f"Error opening serial port: {e}")
        sys.exit(1)
    except Exception as e:
        print_log(f"Unexpected error: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()